define(function(require, exports){
	var $ = require("jquery");
	var util = require('util');
	var pubjs = require('pubjs');
	var view  = require('@base/view');

	// 布局容器
	var Layout = view.container.extend({
		init: function( config ) {
			config = pubjs.conf( config, {
				'class': 'M-tree fl',
				'tab': null, // 选项卡配置信息
				'url': '',
				'showTitle': true,
				'key': 'Id',
				'value': 'Name',
				'Subs': 'Subs',
				'hasLogic': false, // 且或配置
				'type': '' // 人群类型
			});
			this.Super( 'init', arguments );
		},
		afterBuild:function() {
			var el = this.getDOM();
			var C = this.getConfig();
			el.append([
				'<div class="M-treeBox">',
					'<strong class="M-treeBoxTitle">'+LANG('可选条件')+'</strong>',
					'<div class="M-treeSelect" pub-mod="modules/treeSelect.tree" pub-name="tree"/>',
				'</div>',
				'<div class="M-treeArrow">',
					'<i class="triangle-left"/>',
				'</div>',
				'<div class="M-treeBox">',
					'<strong class="M-treeBoxTitle">'+LANG('已选条件')+'</strong>',
					'<div class="M-treeResult" pub-mod="modules/treeSelect.result" pub-name="result"/>',
				'</div>'
			].join(''));
			this.$doms = {
				'select': el.find('.M-treeSelect'), // 左边树容器
				'arrow': el.find('.M-treeArrow'), // 中间箭头
				'result': el.find('.M-treeResult') // 右边结果容器
			}

			if (!C.showTitle) {
				this.find('.M-treeBoxTitle').hide();
			}

			this.buildFromTemplate({
				'tree': {
					'key': C.key,
					'value': C.value,
					'Subs': C.Subs
				},
				'result': {
					'hasLogic': C.hasLogic
				}
			});
			if( C.url ) {
				this.load( C.url );
			}
		},
		load: function( url ) {
			pubjs.sync();
			pubjs.mc.send( url, null, this.onData.bind( this ));
			return this;
		},
		onData: function( err, data ) {
			pubjs.sync(true);
			if( err ) {
				pubjs.error(err);
				pubjs.alert(err.message);
				return false;
			}
			this.buildTab( data );
		},
		// 构建选项卡
		buildTab: function( tabData ) {
			var tree = this.$['tree'];
			tree.buildTab( tabData );
		},
		// 左侧树形选择模块的选项点击消息
		onTreeItemClicked: function( ev ) {
			var param = ev.param;
			var result = this.$['result'];
			var format = _formatTreeData( param );
			// 结果框添加一条
			result.addOne( format );
			return false;
		},
		// 右侧结果选项删除同步到左侧的选中状态
		onResultItemRemove: function( ev ) {
			var id = ev.param;
			var tree = this.$['tree'];
			tree.unChecked( id );
			return false;
		},
		// 树形模块setValue之后再设值result模块
		onTreeItemSetValued: function( ev ) {
			var param = ev.param;
			var mods = this.$;
			var c  = this.getConfig();
			mods['result'].setValue(param, c.type);
			return false;
		},
		// 树形清空已选
		onEmptyTreeItemSelected: function(ev){
			var param = ev.param;
			var result = this.$['result'];
			if(param.length){
				util.each(param, function(item){
					result.addOne(item);
				});
			}
			return false;
		},
		getData: function() {
			var mods = this.$;
			var data = mods['result'].getData();
			return data;
		},
		setValue: function( sets ) {
			var mods = this.$;
			mods['tree'].setValue( sets );
		},
		reset: function() {
			var mods = this.$;
			mods['result'].reset();
			mods['tree'].reset();
		}
	});
	exports.base = Layout;

	// 树容器
	var Tree = view.container.extend({
		init: function( config ) {
			config = pubjs.conf( config, {
				'key': 'Id',
				'value': 'Name',
				'Subs': 'Subs',
				'hasAllSelect': true
			});
			this.Super( 'init', arguments );
		},
		afterBuild:function() {
			var self = this;
			var c = self.getConfig();
			var el = self.getDOM();
			el.append([
				'<div class="M-treeSelectTab">',
					'<ul class="M-treeSelectTabHead uk-tab"/>',
					'<div class="M-treeSelectTabSearch">',
						'<span pub-name="search" pub-mod="@base/common/base.search"/>',
					'</div>',
					'<div class="M-treeSelectTabBox">',
						'<div class="M-treeSelectTabCont" tree-level="root"/>',
						'<div class="M-treeSelectTabCount">0</div>',
					'</div>',
				'</div>'
			].join(''));
			// DOM缓存
			var doms = self.$doms = {
				'tab': el.find('.M-treeSelectTab'),
				'head': el.find('.M-treeSelectTabHead'),
				'search': el.find('.M-treeSelectTabSearch'),
				'box': el.find('.M-treeSelectTabBox'),
				'cont': el.find('.M-treeSelectTabCont'),
				'count': el.find('.M-treeSelectTabCount')
			}

			if(c.hasAllSelect){
				var selectOp = $([
					'<div class="M-treeSelectTabBtns">',
						'<a data-op="all">'+LANG('全选')+'</a>',
						'<a data-op="empty">'+LANG('清空')+'</a>',
					'</div>'
				].join('')).appendTo(el.find('.M-treeSelectTabSearch'));

				self.uiProxy(selectOp, 'a', 'click', 'evetnSelectOp');
			}

			// doms.box.height(el.height() - doms.search.height());

			// 滚动条
			if(util.isMobile()){
				doms.box.css('overflow-y', 'auto');
			}else{
				self.createAsync('scroller', '@base/common/base.scroller', {
					'target': doms.box,
					'content': doms.cont,
					'dir': 'V',
					'watch': 300
				});
			}

			self.buildFromTemplate({
				'search': {
					'addClass': 'simple'
				}
			});

		},
		// 全选和清空
		evetnSelectOp: function(evt, elm){
			var self = this;
			var el = self.getDOM();
			var box = el.find('.M-treeSelectTabContBox:visible');
			var op = $(elm).attr('data-op');
			var inputs = box.find('>li>.itemLabel input');
			if(op == 'all'){
				// 只需模拟点击最高一级，下级的都会选上
				inputs.not(':checked').parent().click();
			}else if(op == 'empty'){
				// 清空已广播形式
				var checks = box.find('input').filter(':checked');
				var emptyData = [];
				checks.each(function(idx, item){
					var id = $(item).val();
					emptyData.push({'id': id});
					self.unChecked(id);
				});
				self.fire('emptyTreeItemSelected', emptyData);


			}
			return false;
		},
		onSearch: function(ev){
			var self = this;
			if(ev.param) {
				self.filterItems(ev.param);
			}else{
				self.$doms.cont.find('li').show();
			}
			return false;
		},
		filterItems: function(val){
			var self = this;
			var key = val.toLowerCase();
			var lists = self.$doms.cont.find('li').hide();
			$.each(lists, function(idx, li){
				var name = $(li).attr('data-name').toLowerCase();
				if( name.indexOf(key) != -1 ) {
					$(li).show().parents('li.item').show();
				}
			});
		},
		// 将配置数据或者拉取的数据转成选项卡数据
		makeTabData: function( tabData ) {
			if( !util.isArray( tabData ) ) {
				return false;
			}
			var C = this.getConfig();

			var i = 0, len = tabData.length, retArr = [];
			for( ; i < len; i++ ) {
				retArr.push({
					'tabId': tabData[i][C.key],
					'text': tabData[i][C.value],
					'data': tabData[i][C.Subs]
				});
			}
			return retArr;
		},
		// 构建选项卡
		buildTab: function( tabData ) {
			var self = this;
			var head = this.$doms['head'];
			var cont = this.$doms['cont'];
			var data = this.makeTabData( tabData );
			var num = data.length; // 选项卡个数
			util.each( data, function( item, idx ) {
				// 构建选项卡选项
				var cls = idx === 0 ? 'uk-active' : '';
				$('<li class="tabItem '+ cls +'" data-id="'+ item['tabId'] +'" data-index="'+ idx +'"/>')
				.html( '<a class="text-truncate">'+LANG(item['text'])+'</a>' )
				.css('width', (100/num)+'%')
				.appendTo( head );
				// 构建选项卡对应的内容容器
				var ulBox = $('<ul class="M-treeSelectTabContBox" tab-id="'+ item['tabId'] +'" tab-text="'+ item['text'] +'"/>')
				.appendTo( cont );
				// 创建选项卡里对应的树形数据
				self.buildTree( item['data'], ulBox );
			});
			head.show();
			cont.find('.M-treeSelectTabContBox').eq(0).show();

			// 选项卡点击切换事件
			this.uiBind( head.find('.tabItem'), 'click', this.eventToggleTab );
			// 折叠/展开选项事件
			this.uiBind( cont.find('.hasSub'), 'click', this.eventToggleOptions );
			// 选项点击事件
			this.uiBind( cont.find('.itemLabel'), 'click', this.eventItemClick );
		},
		// 切换选项卡事件
		eventToggleTab: function( evt, elm ) {
			var index = $(elm).attr('data-index');
			// 切换激活状态
			$(elm).addClass('uk-active').siblings('.tabItem').removeClass('uk-active');
			// 切换容器
			var boxs = this.$doms['cont'].find('.M-treeSelectTabContBox');
			boxs.eq( index ).show().siblings().hide();
		},
		// 创建树形数据, data->树数据; cont->树的放置容器; buildSub->是否是构建子项
		buildTree: function( data, cont, buildSub ) {
			var self = this;
			var target = buildSub ? $('<ul class="M-treeSelectTabContBoxSub"/>').hide() : cont;
			var C = this.getConfig();
			var key = C.key;
			var value = C.value;
			var Subs = C.Subs;
			util.each( data, function( item, idx ) {
				var hasSub = item[Subs] && item[Subs].length; // 子项目的数目
				var subCls = hasSub ? 'hasSub' : 'noSub';
				var id = item[key], prefix = 'for_' + id;
				var sNum = '', separator = '', amount = '';
				if( hasSub && false ) {
					sNum = 0;
					separator = '/';
					amount = self.getSubTotal( item[Subs] );
				}
				var li = $([
					'<li class="item" data-id="'+ id +'" data-name="'+item[value]+'">',
						'<span class="'+ subCls +'"/>',
						'<label for="'+ prefix +'" class="itemLabel">',
							'<input type="checkbox" id="'+ prefix +'" value="'+ id +'"/>',
							LANG(item[value]),
						'</label>',
						'<span class="selectedInfo sNum ml10">'+ sNum +'</span>',
						'<span class="selectedInfo">'+ separator +'</span>',
						'<span class="selectedInfo amount">'+ amount +'</span>',
					'</li>'
				].join(''));
				li.appendTo( target );
				// 如果有子项,生成子项
				if( hasSub ) {
					self.buildTree( item[Subs], li, true );
				}
			});
			// 如果是创建子选项
			if( buildSub ) {
				target.appendTo( cont );
			}

			// 根据有没有hasSub，修正noSub的宽度
			var hasSub_length = target.find('>li>.hasSub').length;
			target.find('>li>.noSub').width(hasSub_length ? 12 : 0);

			self.updateCount();
		},
		// 折叠/展开选项
		eventToggleOptions: function( evt, elm ) {
			var li = $(elm).parent('.item');
			$(elm).toggleClass('openStatus')
			li.toggleClass('open');
			// 折叠状态切换
			if( li.hasClass('open') ) {
				li.children('.M-treeSelectTabContBoxSub').show();
			}
			else {
				li.children('.M-treeSelectTabContBoxSub').hide();
			}
			return false;
		},
		// 选项点击事件, elm -> label.itemLabel
		eventItemClick: function( evt, elm ) {
			// checkbox激活修正
			$(elm).toggleClass('act');
			var input = $(elm).find('input');
			var bool = $(elm).hasClass('act') ? true : false;
			input.prop('checked', bool);
			// 获取当前点击的数据信息
			this.$currentinfo = [];
			var li = $(elm).parent(); // 选中的li
			var parentInfo = this.getParentInfo( li );
			var current = {
				'id': $(elm).find('input').val(),
				'text': $(elm).text()
			}
			parentInfo.unshift( current );
			this.fire( 'treeItemClicked', parentInfo );

			// 如果有子sub，把子sub全选上；
			if(li.find('>ul')){
				var subInputs = li.find('>ul>li>.itemLabel input');
				// toggle
				if(bool){
					subInputs.not(':checked').parent().click();
				}else{
					subInputs.filter(':checked').parent().click();
				}
			}

			// 更新父菜单的选中数目
			// this.updateSelectedNumber( li, +bool );
			if( evt.target.nodeName !== 'INPUT' ) {
				return false;
			}
		},
		// 获取son(li)的上一层li的id和text, preParent->前一个父元素的信息
		getParentInfo: function( son, preParent ) {
			var parent = son.parent(); // ul
			var root = parent.parent(); // 再上一级
			var label = parent.siblings('.itemLabel'); // label
			var level = root.attr('tree-level'); // 再上一级是否是最高层
			var current = {
				'id': label.find('input').val(),
				'text': label.text()
			};
			if( preParent ) {
				this.$currentinfo.push( preParent );
			}
			// 如果再上一级不是root,继续查找
			if( level !== 'root' ) {
				this.getParentInfo( label.parent(), current );
			}
			else {
				this.$currentinfo.push({
					'id': parent.attr('tab-id'),
					'text': parent.attr('tab-text')
				});
			}
			return this.$currentinfo;
		},
		// 获取总子项数
		getSubTotal: function( arr ) {
			var total = 0, i = 0, len = arr.length;
			total += len;
			for( ; i < len; i++ ) {
				var subs = arr[i]['Subs'];
				if( subs.length !== 0 ) {
					total += this.getSubTotal( subs );
				}
			}
			return total;
		},
		// 更新父菜单的选中数目, li->父菜单, n->±1
		updateSelectedNumber: function( li, n ) {
			var i = n === 0 ? -1 : 1; // 加1或减1
			var parent = li.parent().parent(); // 上一个li(父级li)
			var current = +parent.find('.sNum').text(); // 当前选中个数
			parent.children('.sNum').text( current += i );
			if( parent.length !== 0 ) {
				// this.updateSelectedNumber( parent, n );
			}
		},
		// 取消指定id的选中状态
		unChecked: function( id ) {
			this.$doms.cont.find('input[value="'+ id +'"]')
			.prop('checked', false)
			.parent()
			.removeClass('act');
			return this;
		},
		// 更新数目总数
		updateCount: function(){
			var self = this;
			var doms = self.$doms;
			doms.count.text(doms.cont.find('li').length).show();
			return self;
		},
		// 设置默认选中状态
		setValue: function( sets ) {
			var self = this;
			var resultArr = [];
			var cont = self.$doms.cont;
			util.each(sets, function(item){
				if(item){
					var id = item.id;
					var text = item.text;
					var input = cont.find('input[value="'+ id +'"]');
					if(input.length){
						var label = input.parent();
						var li = label.parent();
						self.$currentinfo = [];
						var parentInfo = self.getParentInfo(li);
						parentInfo.unshift({
							'id': id,
							'text': text,
							'logic': item.logic
						});
						resultArr.push(_formatTreeData(parentInfo));
						// label.click();
						input.prop('checked', true);
						label.addClass('act');
					}
				}
			});

			self.fire( 'treeItemSetValued', resultArr);
		},
		setData: function(data){
			if(data){
				this.buildTab(data);
			}
			return this;
		},
		reset: function() {
			this.$doms.cont.find('input')
			.prop('checked', false)
			.parent()
			.removeClass('act');
		}
	});
	exports.tree = Tree;

	// 新选择结果容器
	var Result = view.container.extend({
		init: function( config ) {
			config = pubjs.conf( config, {
				'hasLogic': false
			});

			this.$data = [];

			this.Super( 'init', arguments );
		},
		afterBuild:function(){
			var self = this;
			var c = self.getConfig();
			var el = self.getDOM();
			el.addClass('M-treeResultCon');
			$([
				'<div class="M-treeResultConLogic clear"/>',
				'<div class="M-treeResultConContent">',
					'<ul class="M-treeResultConBox"/>',
				'</div>',
				'<div class="M-treeResultConCount">0</div>'
			].join('')).appendTo(el);

			var doms = self.$doms = {
				'logic': el.find('.M-treeResultConLogic'),
				'content': el.find('.M-treeResultConContent')
			}

			if(c.hasLogic){
				self.createAsync('logic', '@base/common/input.buttonGroup', {
					'target': doms.logic.addClass('pt5 pb5'),
					'items': [LANG('或'), LANG('且')],
					'selected': 0
				});
				doms.logic.css('border-bottom', '1px solid #DDD');
				doms.content.height(el.height() - 40);
			}else{
				doms.content.height(el.height());
			}


			if(util.isMobile()){
				self.$el.css('overflow-y', 'auto');
			}else{
				// 滚动条
				self.createAsync('scroller', '@base/common/base.scroller', {
					'target': el.find('.M-treeResultConContent'),
					'content': el.find('.M-treeResultConBox'),
					'dir': 'V'
					// 'watch': 200
				});
			}

			self.uiProxy(el, 'li.item .remove', 'click', 'eventRemoveOne');

			self.$scrollTime = setInterval(function(){
				self.$.scroller.update();
			}, 200);

		},
		onChangeButton: function(ev){
			return false;
		},
		// 添加一条选中结果
		addOne: function( item ) {
			var self = this;
			var el = self.getDOM();
			if(util.find(self.$data, item.id, 'id')){
				el.find('span[data-id="'+item.id+'"]').parent().remove();
				util.remove(self.$data, item.id, 'id');

			}else{
				self.$data.push(item);
				$([
					'<li class="item">',
						'<span class="resultText fl text-truncate" data-id="'+item.id+'" ms-text="res.texts">',
							item.texts,
						'</span>',
						'<span class="remove fr">×</span>',
					'</li>'
				].join('')).appendTo(el.find('.M-treeResultConBox'));
			}
			self.updateCount(true);
		},
		updateCount: function(showBoolen){
			var self = this;
			var el = self.getDOM();
			var count = el.find('.M-treeResultConCount');
			var length = el.find('.M-treeResultConBox li').length;
			count.text(length)[showBoolen ? 'show' : 'hide']();
			return self;
		},
		eventRemoveOne: function(evt, elm){
			var self = this;
			var id = $(elm).prev().attr('data-id');
			$(elm).parent().remove();
			util.remove(self.$data, id, 'id');
			self.fire('resultItemRemove', id);
			self.updateCount(true);
			return false;
		},
		getData: function() {
			var self = this;
			var result = [];
			var logic = 'or';

			// 处理逻辑运算符
			if(self.get('logic')){
				logic = self.get('logic').getData() == 1 ? 'and' : 'or';
			}

			util.each(self.$data, function(item){
				if(item){
					item.logic = logic;
					result.push(item);
				}
			});

			return result || [];
		},
		setValue: function(sets, type) {
			var self = this;
			var c = self.getConfig();

			// 设置且或
			if(c.hasLogic && self.get('logic')){
				if(sets && sets.length){
					var logic = sets[0].logic == 'and' ? 1 : 0;
					self.get('logic').setData(logic);
				}
			}

			// 设置结果
			util.each(sets, function(item){
				if(item){
					self.addOne(item);
				}
			})

			return self;
		},
		reset: function() {
			this.$data = [];
			this.getDOM().find('.M-treeResultConBox').find('li').remove();
			this.updateCount(false);
			return this;
		}
	});
	exports.result = Result;

	// 添加条件 弹窗内容
	var Popwin = view.widget.extend({
		init: function( config ) {
			config = pubjs.conf( config, {
				'param': null,
				'showTitle': true,  // 是否显示标题
				'isPopwin': true,    // 是否是对话框
				'key': 'Id',
				'value': 'Name',
				'Subs': 'Subs',
				'hasLogic': false,
				'type': ''
			});
			this.$dataReady = false;
			this.$data = null;
			this.$valueCache = null;
			this.Super( 'init', arguments );
		},
		afterBuild:function(){
			var c = this.getConfig();
			var el = this.getDOM();

			el.addClass('pr clear');
			if (c.isPopwin) {
				el.css('padding-top', '5px');
			}

			this.$doms = {
				'module': $('<div class="" pub-mod="modules/treeSelect.base" pub-name="treeSelect"/>').hide().appendTo( el )
			}
			this.buildFromTemplate({
				treeSelect: {
					showTitle: c.showTitle,
					key: c.key,
					value: c.value,
					Subs: c.Subs,
					hasLogic: c.hasLogic,
					type: c.type
				}
			});
		},
		load: function(url) {
			if( !this.$dataReady ) {
				var param = this.getConfig('param');
				this.$doms.module.show();
				this.showLoading();
				pubjs.mc.send( url || param['url'], param.param || {}, this.onData.bind( this ));
			}
			return this;
		},
		onData: function(err, data) {
			if (err) {
				pubjs.error(err);
				pubjs.alert(err.message);
				return false;
			}
			this.setData(data);
			this.fire('treePopDataLoaded');
			this.hideLoading();
		},
		show: function(){
			this.Super( 'show', arguments );
			this.$doms.module.show();
			return this;
		},
		// 构建选项卡
		buildTab: function( data ) {
			this.$['treeSelect'].buildTab( data );
			return this;
		},
		onDialogOk: function( ev ) {
			var data = this.getValue();
			this.fire( 'treeSelected', data );
			return false;
		},
		setData: function( data ) {
			this.$dataReady = true;
			this.$data = data;
			this.buildTab( data );
			//缓存
			if(this.$valueCache){
				this.setValue(this.$valueCache);
				this.$valueCache = null;
			}
			return this;
		},
		getData: function( data ) {
			return this.$data;
		},
		// 设置选中数据
		setValue: function( sets ) {
			if(this.$dataReady){
				this.$['treeSelect'].setValue( sets );
			}else{
				this.$valueCache = sets;
			}
			return this;
		},
		getValue: function(type) {
			return this.$['treeSelect'].getData(type);
		},
		reset: function() {
			this.$valueCache = null;
			// this.hideLoading();
			this.$data = null;
			this.$['treeSelect'].reset();
			return this;
		}
	});
	exports.popwin = Popwin;

	// 将选中的数据格式化
	function _formatTreeData( dataArr ) {
		var i = 0, len = dataArr.length, ret, textArr = [], ids = [];
		for( ; i < len; i++ ) {
			textArr.unshift( dataArr[i].text );
			ids.unshift( dataArr[i].id );
		}
		ret = {
			'ids': ids,
			'texts': textArr.join(' / '),
			'id': dataArr[0]['id'],
			'text': dataArr[0]['text'],
			'logic': dataArr[0]['logic']
		}
		return ret;
	}
});